/*	Castles 

	C.A.D. 						Curso 2011-2012
 	
	Codigo base para la realización de las practicas de CAD

	modulo castle.h

=======================================================

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details 
 http://www.gnu.org/copyleft/gpl.html

=======================================================
Queda prohibido cobrar canon por la copia de este software

*/

// Includes
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>


#ifndef __castlesH__ // Para evitar doble inclusion
#define __castlesH__


/* El siguiente bloque comprueba que modulo se esta compilando de forma que las variables
globales solo se inicialicen cuando se compile el modulo "modelo.c"
*/

#ifndef __modelo__ // No esta compilando modelo, las variables globales son extern

#define ambito extern

#else // Esta compilando  modelo, las variables globales no son extern (se les asigna memoria)

#define ambito

#endif

// ====================================== DEFINES ========================================================


/**
Definicion de identificadores de colores. Los valores se corresponden con la
posicion en la matriz color.
**/
#define amarillo 0
#define gris 1
#define rojo 2
#define	marron 3
#define celeste 4
#define naranja 5
#define verde 6
#define colorfeedback 7
#define azul 8
#define violeta 7


#define MAXNAMES 10
#define MAXOBJETOS 10

ambito int selected;

//========================================  ESTRUCTURAS DE DATOS ==========================================

typedef enum {neutro,paseando,vistaArriba} ESTADO;


typedef enum{ SALIR,ENGANCHAR, DESENGANCHAR, ROTARCAJA, MOVERCAJA,
	PINTARCAJA, DESDEARRIBA, OPERARGRUA, PASEAR, PONERCAJAS
	} opciones_menu;  	// Ident. de opciones del menu



typedef struct{
    //Visualización
    float x;        //Posicion absoluta en x
    float y;        //Posicion absoluta en y
    float z;        //Posicion absoluta en z
    int color;      //Color del proyectil
    float radio;    //Radio
    //Fisica
    float masa;     //Masa en KG
    float angZ;     //Dirección de salida en grados
    float angY;     //Giro del cañon en el eje Y
    float vI;       //Velocidad inicial m/s
    float vX;       //Velocidad en el eje x en tiempo t
    float vY;       //Velocided en el eje y en tiempo t
    float vZ;       //Velocided en el eje y en tiempo t
    float t;        //tiempo de movimiento acumulado
    float caidaX;   //Caida en X
    float caidaZ;   //Caida en Z
    float xInic;
    float yInic;
    float zInic;

    //Velocidades
    float velZ;
    float velY;

    //Estado 0 quieto, 1 disparado
    int disparado;
}proyectil;

typedef struct{
    float x, y, z;          //Posición relativa x, y, z
    int act;                //Determina si es visible
    //Fisica
    float vI;               //Velocidad inicial ms/s
    float vX, vY, vZ;       //Velocidad en el x, y, z para tiempo t
    float angZ, angY;       //Angulo de salida
    float t;                //Tiempo de movimiento acumulado
    float caidX, caidaZ;    //Si trayectoria
    float xInic, yInic, zInic;  //Posición inicial antes del movimiento

    //Velocidad actual
    float velX, velY, velZ;
}bloque;

typedef struct{
    float Xdim, Ydim, Zdim; //Dimensión en x, y, z
    float masa;             //Masa
}bloqueStandar;

/*
Modela una matriz de bloques que contiene la información de cada bloque
perteneciente a un torreon
*/
typedef struct{
    float x, y, z;
    float angZ, angY;
    int nBloqX, nBloqY, nBloqZ;
    bloque Bloque[5][5][5];
}torreon;

typedef struct{
    torreon torre[2];
    //muralla muralla1, muralla2;
    proyectil proy;
    int nJugador; //Numero de jugador
    float color[3];

}jugador;
//================================================ VARIABLES  =============================================

ambito float color[9][4];	// Paleta de colores (se inicializa en initModel)	
ambito int estado;		// Estado en el que se encuentra el programa
ambito int menu;     		// Identificador del menu glut

/**

Angulos de rotacion de la camara.

**/

ambito float view_rotx, view_roty, view_rotz;

/**

Indica el tipo de proyeccion que se esta realizando. Si esta a uno 
se hace proyeccion perspectiva, en caso contrario se hace paralela.

**/
ambito int VISTA_PERSPECTIVA;

/**

Tamanyo para la ventana del mundo en proyeccion paralela.

**/
ambito float ventanaMundoParalela;

/**

Coordenadas x,y de la esquina inferior de la ventana del mundo en vista
paralela.
 
**/
ambito float origenXVentanaMundoParalelo;
ambito float origenYVentanaMundoParalelo;

/**

Distancia de la camara al centro de coordenadas del modelo.

**/
ambito float d;
ambito float x_camara,y_camara,z_camara;
ambito float anchoVentana,altoVentana;

ambito float gravedad;
ambito float auxX, auxY;

ambito GLfloat mat_specular[4];
GLfloat mat_shininess[1];
GLfloat light_position[4];
ambito bloqueStandar bloqueBase;

ambito jugador jugadores[2];

ambito int turno;

// ============================================== FUNCIONES ================================================


// modelo.c

/**
	Funcion de redibujado. Se ejecuta con los eventos postRedisplay
**/
void Dibuja( void );

/**
	Funcion de fondo
**/
void idle();

/**
	Funcion de inicializacion del modelo y de las variables globales
**/
void initModel();

// mouse.c

/**
	Funcion de captura de eventos de pulsacion de botones del raton
	boton: identificador del boton pulsado
	estado: estado del boton
	x: posicion del cursor en coordenadas de pantalla
	y: posicion del cursor en coordenadas de pantalla
**/
void clickRaton( int boton, int estado, int x, int y );
	

/**
	Funcion de captura de eventos de desplazamiento de raton
	x: posicion del cursor en coordenadas de pantalla
	y: posicion del cursor en coordenadas de pantalla
**/
void RatonMovido( int x, int y );


// entradaTeclado.c

/**	
	Funcion de captura de eventos pulsacion de tecla correspondiente a caracter alfanumerico
	K: codigo ascii del caracter
	x: posicion del cursor en coordenadas de pantalla cuando se pulso la tecla
	y: posicion del cursor en coordenadas de pantalla cuando se pulso la tecla
**/
void letra (unsigned char k, int x, int y);

/**
	Funcion de captura de eventos pulsacion de caracteres especiales y de control
	K: codigo del control pulsado (se definen como constantes en glut.h)
	x: posicion del cursor en coordenadas de pantalla cuando se pulso la tecla
	y: posicion del cursor en coordenadas de pantalla cuando se pulso la tecla
**/
void especial(int k, int x, int y);


// entradaMenu.c

void seleccionMenu( int opcion );
// Este procedimiento es llamado por el sistema cuando se selecciona una
// opcion del menu glut. El parametro contiene el identificador de la opcion

 
void CreaMenu();
// Este proc. se usa para definir el menu glut. Se llama desde main.


// estructura.c

void caja( float a, float b, float m);
/* Construye un paralelepipedo alineado con los ejes de
dimension a x b x m. El objeto se construye en el semiespacio y>=0, con el origen en el
centro de la base. 
*/


void falsoCilindro(float h, float r);
/*

Crea un paralelepipedo con sombreado como phong (simulando un cilindro)
con centro de las bases en 0,0,0 y 0,h,0, y radio de la base r.

*/

void falsoCono( float h, float r);
/*

Crea una piramide sombreada como un cono con centro de las bases en
0,0,0, cuspide en  0,h,0, y radio de la base r.

*/


void ejes(float a);
/*
Dibuja unos ejes  de tamaño a
*/


void caja2( float a, float b, float m);
void cajaBorde( float a, float b, float m);
void creaBloque(float dimXCaja, float dimYCaja, float dimZCaja, int x, int y, int z, int col);
void creaVerja(float dimX, float dimY, float dimZ, float x, float y, float z);

void cambioTurno();

void inicJugador (jugador * jugador);

void inicProyectil (proyectil * pProy);

void dibujaJugador(jugador* jug);
/*
Dibuja una esfera de radio rad
*/
void creaEsfera( float rad);

/*
Dibuja un proyectil atendiendo a las coordenadas del mismo
*/
void dibujaProyectil(proyectil * bala);

/*
Dibuja la trayectoria seguida por el proyectil y obtiene su posición de caida
*/
void trayectoria( proyectil * bala);
/*
  Actualiza todas las variables de un proyectil
*/
void actualizaProyectil(proyectil * bala);


// visual.c

void fijaProyeccion();

void transformacionVisualizacion();

void inicializaVentana(GLsizei ancho,GLsizei alto);

void  creaIU();

void drawSeleccionColor();

void DrawPalancas();

void seleccionaPalancas( int boton, int estado, int x, int y);

void muevePalanca( int x, int y);

void seleccionColor( int boton, int estado, int x, int y);


#endif
#undef ambito

